using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Diagnostics;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// 控制器层专用日志扩展
/// 提供统一的API日志记录模式和最佳实践
/// </summary>
public static class ControllerLoggingExtensions
{
    /// <summary>
    /// 记录API操作开始
    /// </summary>
    public static void LogApiStart(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, object? parameters = null, string? userId = null)
    {
        if (parameters != null)
        {
            logger.LogInformation("🚀 API开始: {Action}, 用户: {UserId}, 参数: {@Parameters}", 
                action, userId ?? "匿名", parameters);
        }
        else
        {
            logger.LogInformation("🚀 API开始: {Action}, 用户: {UserId}", action, userId ?? "匿名");
        }
    }

    /// <summary>
    /// 记录API操作成功
    /// </summary>
    public static void LogApiSuccess(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, object? result = null, TimeSpan? elapsed = null, string? userId = null)
    {
        if (result != null && elapsed.HasValue)
        {
            logger.LogInformation("✅ API成功: {Action}, 用户: {UserId}, 耗时: {ElapsedMs:F2}ms, 结果: {@Result}", 
                action, userId ?? "匿名", elapsed.Value.TotalMilliseconds, result);
        }
        else if (elapsed.HasValue)
        {
            logger.LogInformation("✅ API成功: {Action}, 用户: {UserId}, 耗时: {ElapsedMs:F2}ms", 
                action, userId ?? "匿名", elapsed.Value.TotalMilliseconds);
        }
        else if (result != null)
        {
            logger.LogInformation("✅ API成功: {Action}, 用户: {UserId}, 结果: {@Result}", 
                action, userId ?? "匿名", result);
        }
        else
        {
            logger.LogInformation("✅ API成功: {Action}, 用户: {UserId}", action, userId ?? "匿名");
        }
    }

    /// <summary>
    /// 记录API操作失败
    /// </summary>
    public static void LogApiFailure(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, Exception ex, object? parameters = null, string? userId = null)
    {
        if (parameters != null)
        {
            logger.LogError(ex, "❌ API失败: {Action}, 用户: {UserId}, 参数: {@Parameters}, 错误: {ErrorMessage}", 
                action, userId ?? "匿名", parameters, ex.Message);
        }
        else
        {
            logger.LogError(ex, "❌ API失败: {Action}, 用户: {UserId}, 错误: {ErrorMessage}", 
                action, userId ?? "匿名", ex.Message);
        }
    }

    /// <summary>
    /// 记录验证错误
    /// </summary>
    public static void LogValidationError(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string validationErrors, string? userId = null)
    {
        logger.LogWarning("⚠️ 验证错误: {Action}, 用户: {UserId}, 错误: {ValidationErrors}", 
            action, userId ?? "匿名", validationErrors);
    }

    /// <summary>
    /// 记录验证错误（ModelState）
    /// </summary>
    public static void LogValidationError(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, ModelStateDictionary modelState, string? userId = null)
    {
        var errors = modelState
            .Where(x => x.Value?.Errors.Count > 0)
            .ToDictionary(
                kvp => kvp.Key,
                kvp => kvp.Value?.Errors.Select(e => e.ErrorMessage).ToArray()
            );

        logger.LogWarning("⚠️ 模型验证错误: {Action}, 用户: {UserId}, 错误: {@ValidationErrors}", 
            action, userId ?? "匿名", errors);
    }

    /// <summary>
    /// 记录权限拒绝
    /// </summary>
    public static void LogAccessDenied(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string reason, string? userId = null, string? requestedResource = null)
    {
        if (requestedResource != null)
        {
            logger.LogWarning("🚫 访问拒绝: {Action}, 用户: {UserId}, 资源: {RequestedResource}, 原因: {Reason}", 
                action, userId ?? "匿名", requestedResource, reason);
        }
        else
        {
            logger.LogWarning("🚫 访问拒绝: {Action}, 用户: {UserId}, 原因: {Reason}", 
                action, userId ?? "匿名", reason);
        }
    }

    /// <summary>
    /// 记录资源未找到
    /// </summary>
    public static void LogNotFound(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string resourceType, object resourceId, string? userId = null)
    {
        logger.LogInformation("🔍 资源未找到: {Action}, 用户: {UserId}, 资源类型: {ResourceType}, ID: {ResourceId}", 
            action, userId ?? "匿名", resourceType, resourceId);
    }

    /// <summary>
    /// 记录分页查询
    /// </summary>
    public static void LogPagedQuery(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, int pageIndex, int pageSize, int totalCount, 
        TimeSpan? elapsed = null, string? userId = null, object? filters = null)
    {
        if (filters != null && elapsed.HasValue)
        {
            logger.LogInformation("📄 分页查询: {Action}, 用户: {UserId}, 页码: {PageIndex}, 大小: {PageSize}, 总数: {TotalCount}, 耗时: {ElapsedMs:F2}ms, 过滤: {@Filters}", 
                action, userId ?? "匿名", pageIndex, pageSize, totalCount, elapsed.Value.TotalMilliseconds, filters);
        }
        else if (elapsed.HasValue)
        {
            logger.LogInformation("📄 分页查询: {Action}, 用户: {UserId}, 页码: {PageIndex}, 大小: {PageSize}, 总数: {TotalCount}, 耗时: {ElapsedMs:F2}ms", 
                action, userId ?? "匿名", pageIndex, pageSize, totalCount, elapsed.Value.TotalMilliseconds);
        }
        else if (filters != null)
        {
            logger.LogInformation("📄 分页查询: {Action}, 用户: {UserId}, 页码: {PageIndex}, 大小: {PageSize}, 总数: {TotalCount}, 过滤: {@Filters}", 
                action, userId ?? "匿名", pageIndex, pageSize, totalCount, filters);
        }
        else
        {
            logger.LogInformation("📄 分页查询: {Action}, 用户: {UserId}, 页码: {PageIndex}, 大小: {PageSize}, 总数: {TotalCount}", 
                action, userId ?? "匿名", pageIndex, pageSize, totalCount);
        }
    }

    /// <summary>
    /// 记录批量操作
    /// </summary>
    public static void LogBatchOperation(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, int itemCount, int successCount, int failureCount, 
        TimeSpan? elapsed = null, string? userId = null)
    {
        var message = elapsed.HasValue 
            ? "🔄 批量操作: {Action}, 用户: {UserId}, 总数: {ItemCount}, 成功: {SuccessCount}, 失败: {FailureCount}, 耗时: {ElapsedMs:F2}ms"
            : "🔄 批量操作: {Action}, 用户: {UserId}, 总数: {ItemCount}, 成功: {SuccessCount}, 失败: {FailureCount}";

        if (failureCount > 0)
        {
            if (elapsed.HasValue)
            {
                logger.LogWarning(message, action, userId ?? "匿名", itemCount, successCount, failureCount, elapsed.Value.TotalMilliseconds);
            }
            else
            {
                logger.LogWarning(message, action, userId ?? "匿名", itemCount, successCount, failureCount);
            }
        }
        else
        {
            if (elapsed.HasValue)
            {
                logger.LogInformation(message, action, userId ?? "匿名", itemCount, successCount, failureCount, elapsed.Value.TotalMilliseconds);
            }
            else
            {
                logger.LogInformation(message, action, userId ?? "匿名", itemCount, successCount, failureCount);
            }
        }
    }

    /// <summary>
    /// 记录文件操作
    /// </summary>
    public static void LogFileOperation(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string operation, string fileName, long? fileSize = null, 
        string? contentType = null, string? userId = null)
    {
        if (fileSize.HasValue && contentType != null)
        {
            logger.LogInformation("📁 文件操作: {Action}/{Operation}, 用户: {UserId}, 文件: {FileName}, 大小: {FileSize} bytes, 类型: {ContentType}", 
                action, operation, userId ?? "匿名", fileName, fileSize.Value, contentType);
        }
        else if (fileSize.HasValue)
        {
            logger.LogInformation("📁 文件操作: {Action}/{Operation}, 用户: {UserId}, 文件: {FileName}, 大小: {FileSize} bytes", 
                action, operation, userId ?? "匿名", fileName, fileSize.Value);
        }
        else
        {
            logger.LogInformation("📁 文件操作: {Action}/{Operation}, 用户: {UserId}, 文件: {FileName}", 
                action, operation, userId ?? "匿名", fileName);
        }
    }

    /// <summary>
    /// 记录缓存操作
    /// </summary>
    public static void LogCacheOperation(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string operation, string cacheKey, bool hit, TimeSpan? elapsed = null)
    {
        var status = hit ? "命中" : "未命中";
        if (elapsed.HasValue)
        {
            logger.LogInformation("💾 缓存操作: {Action}/{Operation}, 键: {CacheKey}, 状态: {Status}, 耗时: {ElapsedMs:F2}ms", 
                action, operation, cacheKey, status, elapsed.Value.TotalMilliseconds);
        }
        else
        {
            logger.LogInformation("💾 缓存操作: {Action}/{Operation}, 键: {CacheKey}, 状态: {Status}", 
                action, operation, cacheKey, status);
        }
    }

    /// <summary>
    /// 记录慢查询警告
    /// </summary>
    public static void LogSlowQuery(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, TimeSpan elapsed, int threshold = 1000, object? queryInfo = null, string? userId = null)
    {
        if (elapsed.TotalMilliseconds > threshold)
        {
            if (queryInfo != null)
            {
                logger.LogWarning("🐌 慢查询警告: {Action}, 用户: {UserId}, 耗时: {ElapsedMs:F2}ms (阈值: {Threshold}ms), 查询: {@QueryInfo}", 
                    action, userId ?? "匿名", elapsed.TotalMilliseconds, threshold, queryInfo);
            }
            else
            {
                logger.LogWarning("🐌 慢查询警告: {Action}, 用户: {UserId}, 耗时: {ElapsedMs:F2}ms (阈值: {Threshold}ms)", 
                    action, userId ?? "匿名", elapsed.TotalMilliseconds, threshold);
            }
        }
    }

    /// <summary>
    /// 记录外部服务调用
    /// </summary>
    public static void LogExternalServiceCall(this Microsoft.Extensions.Logging.ILogger logger, 
        string action, string serviceName, string endpoint, int statusCode, 
        TimeSpan elapsed, object? requestData = null, string? userId = null)
    {
        var level = statusCode >= 400 ? LogLevel.Warning : LogLevel.Information;
        var emoji = statusCode >= 400 ? "⚠️" : "🌐";

        if (requestData != null)
        {
            logger.Log(level, "{Emoji} 外部服务: {Action}, 用户: {UserId}, 服务: {ServiceName}, 端点: {Endpoint}, 状态: {StatusCode}, 耗时: {ElapsedMs:F2}ms, 请求: {@RequestData}", 
                emoji, action, userId ?? "匿名", serviceName, endpoint, statusCode, elapsed.TotalMilliseconds, requestData);
        }
        else
        {
            logger.Log(level, "{Emoji} 外部服务: {Action}, 用户: {UserId}, 服务: {ServiceName}, 端点: {Endpoint}, 状态: {StatusCode}, 耗时: {ElapsedMs:F2}ms", 
                emoji, action, userId ?? "匿名", serviceName, endpoint, statusCode, elapsed.TotalMilliseconds);
        }
    }

    /// <summary>
    /// 获取当前用户ID（从HttpContext）
    /// </summary>
    public static string? GetCurrentUserId(this ControllerBase controller)
    {
        var httpContext = controller.HttpContext;
        if (httpContext?.User?.Identity?.IsAuthenticated == true)
        {
            return httpContext.User.Identity.Name ?? 
                   httpContext.User.FindFirst("sub")?.Value ?? 
                   httpContext.User.FindFirst("id")?.Value;
        }
        return null;
    }

    /// <summary>
    /// 创建性能测量器
    /// </summary>
    public static IDisposable MeasureApiPerformance(this Microsoft.Extensions.Logging.ILogger logger, string action, string? userId = null)
    {
        return new ApiPerformanceMeasurer(logger, action, userId);
    }
}

/// <summary>
/// API性能测量器
/// </summary>
internal class ApiPerformanceMeasurer : IDisposable
{
    private readonly Microsoft.Extensions.Logging.ILogger _logger;
    private readonly string _action;
    private readonly string? _userId;
    private readonly Stopwatch _stopwatch;

    public ApiPerformanceMeasurer(Microsoft.Extensions.Logging.ILogger logger, string action, string? userId)
    {
        _logger = logger;
        _action = action;
        _userId = userId;
        _stopwatch = Stopwatch.StartNew();
    }

    public void Dispose()
    {
        _stopwatch.Stop();
        var elapsed = _stopwatch.Elapsed;
        
        // 根据耗时确定日志级别
        var level = elapsed.TotalMilliseconds switch
        {
            > 5000 => LogLevel.Warning, // 超过5秒
            > 1000 => LogLevel.Information, // 超过1秒
            _ => LogLevel.Debug // 正常情况
        };

        _logger.Log(level, "⚡ API性能: {Action}, 用户: {UserId}, 总耗时: {ElapsedMs:F2}ms", 
            _action, _userId ?? "匿名", elapsed.TotalMilliseconds);
    }
}
